package org.iamd.domain.data;

import java.io.Serializable;
import java.util.List;

/**
 * Предоставя функционалност за работа с бази данни и други repository-та на данни. Идентификаторите
 * на обектите с които интерфейсът работи трябва да имплементират {@link Serializable}
 * 
 * @param <D>
 *            Data обекти, с които Layer-а работи
 * @param <C>
 *            Критерии за конкретния Data Access Layer
 * 
 * @author И. Атанасов
 */
public interface IDataAccess<D extends IData, C extends Object> {

	/**
	 * Инициализира транзакция към съответното репозитори.
	 * 
	 * @throws DataAccessException
	 *             при неуспешна инициализация
	 */
	public void beginWork() throws DataAccessException;

	/**
	 * Commit-ва транзакция към съответното репозитори.
	 * 
	 * @throws DataAccessException
	 *             при неуспешен commit
	 */
	public abstract void commitWork() throws DataAccessException;

	/**
	 * @return създаване на празен критерии
	 */
	public abstract C createCriteria();

	/**
	 * @return създаване на празна инстанция на VO
	 * 
	 * @throws DataAccessException
	 *             при неуспешно инстанциране на VO
	 */
	public D createInstance() throws DataAccessException;

	/**
	 * Изтрива обект от repository на данни.
	 * 
	 * @param data
	 *            обектът, който трябва да бъде изтрит
	 * 
	 * @throws DataAccessException
	 *             при неуспешно изтриване
	 */
	public abstract void delete(D data) throws DataAccessException;

	/**
	 * Намира списък от обекти по подадени критерии.
	 * 
	 * @param criteria
	 *            входни критерии
	 * 
	 * @return списък с обекти, които съответстват на критериите
	 * 
	 * @throws DataAccessException
	 *             при изключение възникнало при интеракция с репозиторито
	 */
	public abstract List<D> findByCriteria(C criteria) throws DataAccessException;

	/**
	 * Намира обект по системен идентификатор.
	 * 
	 * @param id
	 *            системен идентификатор на обекта
	 * 
	 * @return намереният обект или <code>null</code> ако не е намерен
	 * 
	 * @throws DataAccessException
	 *             при изключение възникнало при интеракция с репозиторито
	 * 
	 */
	public abstract D findById(Serializable id) throws DataAccessException;

	/**
	 * Rollback на транзакция към съответното репозитори.
	 * 
	 * @throws DataAccessException
	 *             при неуспешен rollback
	 */
	public abstract void rollback() throws DataAccessException;

	/**
	 * Записва обект в repository на данни.
	 * 
	 * @param data
	 *            обектът, който трябва да бъде съхранен
	 * 
	 * @throws DataAccessException
	 *             при неуспешен запис
	 */
	public abstract void save(D data) throws DataAccessException;

	/**
	 * Актуализира обект в repository на данни.
	 * 
	 * @param data
	 *            обектът, който трябва да бъде обновен
	 * 
	 * @throws DataAccessException
	 *             при неуспешен update
	 */
	public abstract void update(D data) throws DataAccessException;

}